{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "wdl_movielens.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "hbZyx5YQN5lE",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "outputId": "9215bc08-dc62-4a94-d264-033571df1268"
      },
      "source": [
        "#%%\n",
        "import pandas as pd\n",
        "from sklearn.metrics import mean_squared_error\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.preprocessing import LabelEncoder\n",
        "\n",
        "from deepctr.models import WDL\n",
        "from deepctr.feature_column import SparseFeat,get_feature_names\n",
        "\n",
        "data = pd.read_csv(\"./drive/My Drive/movielens_sample.txt\")\n",
        "sparse_features = [\"movie_id\", \"user_id\", \"gender\", \"age\", \"occupation\", \"zip\"]\n",
        "target = ['rating']\n",
        "\n",
        "# 对特征标签进行编码\n",
        "for feature in sparse_features:\n",
        "    lbe = LabelEncoder()\n",
        "    data[feature] = lbe.fit_transform(data[feature])\n",
        "# 计算每个特征中的 不同特征值的个数\n",
        "fixlen_feature_columns = [SparseFeat(feature, data[feature].nunique()) for feature in sparse_features]\n",
        "linear_feature_columns = fixlen_feature_columns\n",
        "dnn_feature_columns = fixlen_feature_columns\n",
        "feature_names = get_feature_names(linear_feature_columns + dnn_feature_columns)\n",
        "\n",
        "# 将数据集切分成训练集和测试集\n",
        "train, test = train_test_split(data, test_size=0.2)\n",
        "train_model_input = {name:train[name].values for name in feature_names}\n",
        "test_model_input = {name:test[name].values for name in feature_names}\n",
        "\n",
        "# 使用WDL进行训练\n",
        "model = WDL(linear_feature_columns, dnn_feature_columns, task='regression')\n",
        "model.compile(\"adam\", \"mse\", metrics=['mse'], )\n",
        "history = model.fit(train_model_input, train[target].values, batch_size=256, epochs=50, verbose=True, validation_split=0.2, )\n",
        "# 使用WDL进行预测\n",
        "pred_ans = model.predict(test_model_input, batch_size=256)\n",
        "# 输出RMSE或MSE\n",
        "mse = round(mean_squared_error(test[target].values, pred_ans), 4)\n",
        "rmse = mse ** 0.5\n",
        "print(\"test RMSE\", rmse)"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 1/50\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/indexed_slices.py:432: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.\n",
            "  \"Converting sparse IndexedSlices to a dense Tensor of unknown shape. \"\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "1/1 [==============================] - 0s 341ms/step - loss: 13.8202 - mse: 13.8202 - val_loss: 14.7540 - val_mse: 14.7540\n",
            "Epoch 2/50\n",
            "1/1 [==============================] - 0s 24ms/step - loss: 13.6840 - mse: 13.6840 - val_loss: 14.6265 - val_mse: 14.6265\n",
            "Epoch 3/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 13.5388 - mse: 13.5388 - val_loss: 14.4904 - val_mse: 14.4904\n",
            "Epoch 4/50\n",
            "1/1 [==============================] - 0s 20ms/step - loss: 13.3840 - mse: 13.3840 - val_loss: 14.3458 - val_mse: 14.3458\n",
            "Epoch 5/50\n",
            "1/1 [==============================] - 0s 27ms/step - loss: 13.2200 - mse: 13.2200 - val_loss: 14.1920 - val_mse: 14.1920\n",
            "Epoch 6/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 13.0460 - mse: 13.0460 - val_loss: 14.0287 - val_mse: 14.0287\n",
            "Epoch 7/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 12.8612 - mse: 12.8612 - val_loss: 13.8553 - val_mse: 13.8553\n",
            "Epoch 8/50\n",
            "1/1 [==============================] - 0s 24ms/step - loss: 12.6651 - mse: 12.6651 - val_loss: 13.6709 - val_mse: 13.6709\n",
            "Epoch 9/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 12.4570 - mse: 12.4570 - val_loss: 13.4750 - val_mse: 13.4750\n",
            "Epoch 10/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 12.2360 - mse: 12.2360 - val_loss: 13.2669 - val_mse: 13.2669\n",
            "Epoch 11/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 12.0014 - mse: 12.0014 - val_loss: 13.0459 - val_mse: 13.0459\n",
            "Epoch 12/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 11.7524 - mse: 11.7524 - val_loss: 12.8113 - val_mse: 12.8113\n",
            "Epoch 13/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 11.4879 - mse: 11.4879 - val_loss: 12.5626 - val_mse: 12.5626\n",
            "Epoch 14/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 11.2072 - mse: 11.2072 - val_loss: 12.2993 - val_mse: 12.2993\n",
            "Epoch 15/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 10.9092 - mse: 10.9092 - val_loss: 12.0205 - val_mse: 12.0205\n",
            "Epoch 16/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 10.5931 - mse: 10.5931 - val_loss: 11.7261 - val_mse: 11.7261\n",
            "Epoch 17/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 10.2584 - mse: 10.2584 - val_loss: 11.4151 - val_mse: 11.4151\n",
            "Epoch 18/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 9.9044 - mse: 9.9044 - val_loss: 11.0870 - val_mse: 11.0870\n",
            "Epoch 19/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 9.5306 - mse: 9.5306 - val_loss: 10.7413 - val_mse: 10.7413\n",
            "Epoch 20/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 9.1369 - mse: 9.1369 - val_loss: 10.3778 - val_mse: 10.3778\n",
            "Epoch 21/50\n",
            "1/1 [==============================] - 0s 20ms/step - loss: 8.7234 - mse: 8.7234 - val_loss: 9.9963 - val_mse: 9.9963\n",
            "Epoch 22/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 8.2908 - mse: 8.2908 - val_loss: 9.5963 - val_mse: 9.5963\n",
            "Epoch 23/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 7.8407 - mse: 7.8407 - val_loss: 9.1783 - val_mse: 9.1782\n",
            "Epoch 24/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 7.3736 - mse: 7.3736 - val_loss: 8.7431 - val_mse: 8.7431\n",
            "Epoch 25/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 6.8911 - mse: 6.8911 - val_loss: 8.2920 - val_mse: 8.2920\n",
            "Epoch 26/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 6.3955 - mse: 6.3955 - val_loss: 7.8262 - val_mse: 7.8262\n",
            "Epoch 27/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 5.8897 - mse: 5.8897 - val_loss: 7.3472 - val_mse: 7.3471\n",
            "Epoch 28/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 5.3774 - mse: 5.3774 - val_loss: 6.8575 - val_mse: 6.8574\n",
            "Epoch 29/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 4.8630 - mse: 4.8630 - val_loss: 6.3600 - val_mse: 6.3600\n",
            "Epoch 30/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 4.3520 - mse: 4.3519 - val_loss: 5.8582 - val_mse: 5.8582\n",
            "Epoch 31/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 3.8505 - mse: 3.8504 - val_loss: 5.3562 - val_mse: 5.3561\n",
            "Epoch 32/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 3.3658 - mse: 3.3658 - val_loss: 4.8584 - val_mse: 4.8584\n",
            "Epoch 33/50\n",
            "1/1 [==============================] - 0s 24ms/step - loss: 2.9061 - mse: 2.9060 - val_loss: 4.3705 - val_mse: 4.3705\n",
            "Epoch 34/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 2.4800 - mse: 2.4800 - val_loss: 3.8986 - val_mse: 3.8985\n",
            "Epoch 35/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 2.0967 - mse: 2.0967 - val_loss: 3.4489 - val_mse: 3.4488\n",
            "Epoch 36/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 1.7651 - mse: 1.7650 - val_loss: 3.0280 - val_mse: 3.0280\n",
            "Epoch 37/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 1.4931 - mse: 1.4931 - val_loss: 2.6436 - val_mse: 2.6436\n",
            "Epoch 38/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.2871 - mse: 1.2871 - val_loss: 2.3018 - val_mse: 2.3018\n",
            "Epoch 39/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 1.1501 - mse: 1.1501 - val_loss: 2.0077 - val_mse: 2.0077\n",
            "Epoch 40/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.0805 - mse: 1.0805 - val_loss: 1.7650 - val_mse: 1.7650\n",
            "Epoch 41/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.0702 - mse: 1.0701 - val_loss: 1.5736 - val_mse: 1.5736\n",
            "Epoch 42/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.1039 - mse: 1.1039 - val_loss: 1.4309 - val_mse: 1.4309\n",
            "Epoch 43/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.1607 - mse: 1.1607 - val_loss: 1.3318 - val_mse: 1.3318\n",
            "Epoch 44/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 1.2177 - mse: 1.2177 - val_loss: 1.2696 - val_mse: 1.2696\n",
            "Epoch 45/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.2547 - mse: 1.2547 - val_loss: 1.2381 - val_mse: 1.2381\n",
            "Epoch 46/50\n",
            "1/1 [==============================] - 0s 23ms/step - loss: 1.2582 - mse: 1.2581 - val_loss: 1.2323 - val_mse: 1.2323\n",
            "Epoch 47/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 1.2232 - mse: 1.2232 - val_loss: 1.2491 - val_mse: 1.2491\n",
            "Epoch 48/50\n",
            "1/1 [==============================] - 0s 22ms/step - loss: 1.1529 - mse: 1.1529 - val_loss: 1.2867 - val_mse: 1.2867\n",
            "Epoch 49/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 1.0560 - mse: 1.0560 - val_loss: 1.3442 - val_mse: 1.3441\n",
            "Epoch 50/50\n",
            "1/1 [==============================] - 0s 21ms/step - loss: 0.9440 - mse: 0.9440 - val_loss: 1.4205 - val_mse: 1.4205\n",
            "test RMSE 1.2206965224821442\n"
          ],
          "name": "stdout"
        }
      ]
    }
  ]
}